package com.cinema;

import com.cinema.model.*;
import com.cinema.service.*;
import com.cinema.util.Logger;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeParseException;
import java.util.*;

/**
 * 电影院管理系统主程序
 * 版本 0.3.0 - 完整功能实现
 */
public class Main {
    private static AuthenticationService authService;
    private static MovieService movieService;
    private static CinemaService cinemaService;
    private static TicketService ticketService;
    private static Scanner scanner;
    private static User currentUser;

    public static void main(String[] args) {
        initializeServices();

        System.out.println("==========================================");
        System.out.println("      万东电影院管理系统");
        System.out.println("      版本: 0.3.0 - 完整功能");
        System.out.println("==========================================");

        runMainLoop();
        cleanup();
    }

    private static void initializeServices() {
        System.out.println("正在初始化系统服务...");
        authService = new AuthenticationService();
        movieService = new MovieService();
        cinemaService = new CinemaService();
        ticketService = new TicketService();
        scanner = new Scanner(System.in);
        System.out.println("系统服务初始化完成");
    }

    private static void runMainLoop() {
        boolean running = true;

        while (running) {
            showMainMenu();
            int choice = getIntInput("请选择操作: ");

            switch (choice) {
                case 1:
                    handleLogin();
                    break;
                case 2:
                    showSystemInfo();
                    break;
                case 3:
                    running = false;
                    break;
                default:
                    System.out.println("无效选择，请重新输入！");
            }
        }
    }

    private static void showMainMenu() {
        System.out.println("\n=== 主菜单 ===");
        System.out.println("1. 用户登录");
        System.out.println("2. 系统信息");
        System.out.println("3. 退出系统");
        System.out.println("=============");
    }

    private static void handleLogin() {
        System.out.println("\n--- 用户登录 ---");
        System.out.print("请输入用户名: ");
        String username = scanner.nextLine();
        System.out.print("请输入密码: ");
        String password = scanner.nextLine();

        User user = authService.login(username, password);
        if (user != null) {
            System.out.println("✔ 登录成功！欢迎 " + user.getUsername());
            Logger.info("用户登录成功", user.getUsername());
            showUserMenu(user);
        } else {
            System.out.println("✘ 登录失败，用户名或密码错误！");
            Logger.warn("登录失败尝试", username);
        }
    }

    private static void showUserMenu(User user) {
        currentUser = user;
        switch (user.getUserType()) {
            case "admin":
                showAdminMenu();
                break;
            case "manager":
                showManagerMenu();
                break;
            case "frontdesk":
                showFrontDeskMenu();
                break;
        }
    }

    // ==================== 管理员菜单 ====================
    private static void showAdminMenu() {
        while (true) {
            System.out.println("\n=== 管理员菜单 ===");
            System.out.println("1. 用户管理");
            System.out.println("2. 电影管理");
            System.out.println("3. 场次管理");
            System.out.println("4. 销售统计");
            System.out.println("5. 系统信息");
            System.out.println("6. 退出登录");
            System.out.println("=================");

            int choice = getIntInput("请选择操作: ");
            switch (choice) {
                case 1: manageUsers(); break;
                case 2: manageMovies(); break;
                case 3: manageScreenings(); break;
                case 4: showStatistics(); break;
                case 5: showSystemInfo(); break;
                case 6:
                    Logger.info("管理员退出登录", currentUser.getUsername());
                    return;
                default: System.out.println("无效选择！");
            }
        }
    }

    private static void manageUsers() {
        System.out.println("\n用户管理功能待实现...");
        // 这里可以实现用户管理的具体功能
    }

    private static void manageMovies() {
        while (true) {
            System.out.println("\n=== 电影管理 ===");
            System.out.println("1. 添加电影");
            System.out.println("2. 查看所有电影");
            System.out.println("3. 查看上映中电影");
            System.out.println("4. 搜索电影");
            System.out.println("5. 修改电影信息");
            System.out.println("6. 删除电影");
            System.out.println("7. 返回上级");
            System.out.println("===============");

            int choice = getIntInput("请选择操作: ");
            switch (choice) {
                case 1: addMovie(); break;
                case 2: listAllMovies(); break;
                case 3: listShowingMovies(); break;
                case 4: searchMovies(); break;
                case 5: updateMovie(); break;
                case 6: deleteMovie(); break;
                case 7: return;
                default: System.out.println("无效选择！");
            }
        }
    }

    private static void addMovie() {
        System.out.println("\n--- 添加新电影 ---");
        String movieId = "M" + System.currentTimeMillis();
        System.out.print("电影名称: ");
        String title = scanner.nextLine();
        System.out.print("导演: ");
        String director = scanner.nextLine();
        System.out.print("主演(用逗号分隔): ");
        String[] actorsArray = scanner.nextLine().split(",");
        List<String> actors = Arrays.asList(actorsArray);
        System.out.print("剧情简介: ");
        String description = scanner.nextLine();
        System.out.print("时长(分钟): ");
        int duration = getIntInput("");
        System.out.print("评分(0-10): ");
        double rating = getDoubleInput("");

        Movie movie = new Movie(movieId, title, director, actors, description, duration, rating);
        if (movieService.addMovie(movie)) {
            System.out.println("电影添加成功！");
            Logger.info("添加电影: " + title, currentUser.getUsername());
        } else {
            System.out.println("电影添加失败！");
        }
    }

    private static void listAllMovies() {
        List<Movie> movies = movieService.getAllMovies();
        if (movies.isEmpty()) {
            System.out.println("暂无电影信息");
            return;
        }

        System.out.println("\n=== 所有电影 ===");
        for (int i = 0; i < movies.size(); i++) {
            Movie movie = movies.get(i);
            String status = movie.isShowing() ? "上映中" : "已下架";
            System.out.printf("%d. %s [%s]%n", i + 1, movie, status);
        }
    }

    private static void listShowingMovies() {
        List<Movie> movies = movieService.getShowingMovies();
        if (movies.isEmpty()) {
            System.out.println("暂无上映中电影");
            return;
        }

        System.out.println("\n=== 上映中电影 ===");
        for (int i = 0; i < movies.size(); i++) {
            System.out.println((i + 1) + ". " + movies.get(i));
        }
    }

    private static void searchMovies() {
        System.out.print("\n请输入搜索关键词: ");
        String keyword = scanner.nextLine();
        List<Movie> results = movieService.searchMovies(keyword);

        if (results.isEmpty()) {
            System.out.println("未找到相关电影");
            return;
        }

        System.out.println("\n=== 搜索结果 ===");
        for (int i = 0; i < results.size(); i++) {
            System.out.println((i + 1) + ". " + results.get(i));
        }
    }

    private static void updateMovie() {
        listAllMovies();
        System.out.print("\n请输入要修改的电影编号: ");
        int index = getIntInput("") - 1;
        List<Movie> movies = movieService.getAllMovies();

        if (index < 0 || index >= movies.size()) {
            System.out.println("无效的电影编号");
            return;
        }

        Movie movie = movies.get(index);
        System.out.println("当前信息: " + movie);

        System.out.print("新电影名称(直接回车保持原值): ");
        String title = scanner.nextLine();
        if (!title.isEmpty()) movie.setTitle(title);

        System.out.print("新导演(直接回车保持原值): ");
        String director = scanner.nextLine();
        if (!director.isEmpty()) movie.setDirector(director);

        System.out.print("新评分(0-10, 直接回车保持原值): ");
        String ratingInput = scanner.nextLine();
        if (!ratingInput.isEmpty()) {
            try {
                double rating = Double.parseDouble(ratingInput);
                movie.setRating(rating);
            } catch (NumberFormatException e) {
                System.out.println("评分格式错误，保持原值");
            }
        }

        if (movieService.updateMovie(movie.getMovieId(), movie)) {
            System.out.println("电影信息更新成功！");
            Logger.info("更新电影信息: " + movie.getTitle(), currentUser.getUsername());
        } else {
            System.out.println("电影信息更新失败！");
        }
    }

    private static void deleteMovie() {
        listAllMovies();
        System.out.print("\n请输入要删除的电影编号: ");
        int index = getIntInput("") - 1;
        List<Movie> movies = movieService.getAllMovies();

        if (index < 0 || index >= movies.size()) {
            System.out.println("无效的电影编号");
            return;
        }

        Movie movie = movies.get(index);
        System.out.print("确定要删除电影《" + movie.getTitle() + "》吗？(y/N): ");
        String confirm = scanner.nextLine();

        if ("y".equalsIgnoreCase(confirm)) {
            if (movieService.deleteMovie(movie.getMovieId())) {
                System.out.println("电影删除成功！");
                Logger.info("删除电影: " + movie.getTitle(), currentUser.getUsername());
            } else {
                System.out.println("电影删除失败！");
            }
        } else {
            System.out.println("取消删除操作");
        }
    }

    private static void manageScreenings() {
        while (true) {
            System.out.println("\n=== 场次管理 ===");
            System.out.println("1. 添加场次");
            System.out.println("2. 查看所有场次");
            System.out.println("3. 查看本周场次");
            System.out.println("4. 查看今日场次");
            System.out.println("5. 修改场次");
            System.out.println("6. 删除场次");
            System.out.println("7. 查看影厅信息");
            System.out.println("8. 返回上级");
            System.out.println("===============");

            int choice = getIntInput("请选择操作: ");
            switch (choice) {
                case 1: addScreening(); break;
                case 2: listAllScreenings(); break;
                case 3: listThisWeekScreenings(); break;
                case 4: listTodayScreenings(); break;
                case 5: updateScreening(); break;
                case 6: deleteScreening(); break;
                case 7: listCinemaHalls(); break;
                case 8: return;
                default: System.out.println("无效选择！");
            }
        }
    }

    private static void addScreening() {
        // 选择电影
        List<Movie> movies = movieService.getShowingMovies();
        if (movies.isEmpty()) {
            System.out.println("暂无上映中电影，请先添加电影");
            return;
        }

        System.out.println("\n=== 选择电影 ===");
        for (int i = 0; i < movies.size(); i++) {
            System.out.println((i + 1) + ". " + movies.get(i).getTitle());
        }

        int movieIndex = getIntInput("请选择电影编号: ") - 1;
        if (movieIndex < 0 || movieIndex >= movies.size()) {
            System.out.println("无效的电影编号");
            return;
        }
        Movie selectedMovie = movies.get(movieIndex);

        // 选择影厅
        List<CinemaHall> halls = cinemaService.getAllHalls();
        System.out.println("\n=== 选择影厅 ===");
        for (int i = 0; i < halls.size(); i++) {
            CinemaHall hall = halls.get(i);
            System.out.printf("%d. %s (%d排%d座)%n",
                    i + 1, hall.getHallName(), hall.getRows(), hall.getSeatsPerRow());
        }

        int hallIndex = getIntInput("请选择影厅编号: ") - 1;
        if (hallIndex < 0 || hallIndex >= halls.size()) {
            System.out.println("无效的影厅编号");
            return;
        }
        CinemaHall selectedHall = halls.get(hallIndex);

        // 输入时间
        System.out.print("请输入开始时间 (格式: yyyy-MM-dd HH:mm): ");
        String timeInput = scanner.nextLine();
        LocalDateTime startTime;
        try {
            startTime = LocalDateTime.parse(timeInput,
                    DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm"));
        } catch (DateTimeParseException e) {
            System.out.println("时间格式错误，使用当前时间");
            startTime = LocalDateTime.now().plusHours(1);
        }

        // 输入价格
        System.out.print("请输入票价: ");
        double price = getDoubleInput("");

        // 创建场次
        String screeningId = "S" + System.currentTimeMillis();
        Screening screening = new Screening(screeningId, selectedMovie, selectedHall, startTime, price);

        if (cinemaService.addScreening(screening)) {
            System.out.println("场次添加成功！");
            Logger.info("添加场次: " + selectedMovie.getTitle() + " - " +
                    selectedHall.getHallName(), currentUser.getUsername());
        } else {
            System.out.println("场次添加失败！");
        }
    }

    private static void listAllScreenings() {
        List<Screening> screenings = cinemaService.getAllScreenings();
        if (screenings.isEmpty()) {
            System.out.println("暂无场次信息");
            return;
        }

        System.out.println("\n=== 所有场次 ===");
        for (int i = 0; i < screenings.size(); i++) {
            System.out.println((i + 1) + ". " + screenings.get(i));
        }
    }

    private static void listThisWeekScreenings() {
        List<Screening> screenings = cinemaService.getScreeningsThisWeek();
        if (screenings.isEmpty()) {
            System.out.println("本周暂无场次");
            return;
        }

        System.out.println("\n=== 本周场次 ===");
        for (int i = 0; i < screenings.size(); i++) {
            System.out.println((i + 1) + ". " + screenings.get(i));
        }
    }

    private static void listTodayScreenings() {
        List<Screening> screenings = cinemaService.getScreeningsByDate(LocalDateTime.now());
        if (screenings.isEmpty()) {
            System.out.println("今日暂无场次");
            return;
        }

        System.out.println("\n=== 今日场次 ===");
        for (int i = 0; i < screenings.size(); i++) {
            System.out.println((i + 1) + ". " + screenings.get(i));
        }
    }

    private static void listCinemaHalls() {
        List<CinemaHall> halls = cinemaService.getAllHalls();
        System.out.println("\n=== 影厅信息 ===");
        for (CinemaHall hall : halls) {
            System.out.printf("%s: %d排%d座，总座位数: %d，空闲座位: %d%n",
                    hall.getHallName(), hall.getRows(), hall.getSeatsPerRow(),
                    hall.getTotalSeats(), hall.getAvailableSeatsCount());
        }
    }

    private static void updateScreening() {
        listAllScreenings();
        System.out.print("\n请输入要修改的场次编号: ");
        int index = getIntInput("") - 1;
        List<Screening> screenings = cinemaService.getAllScreenings();

        if (index < 0 || index >= screenings.size()) {
            System.out.println("无效的场次编号");
            return;
        }

        Screening screening = screenings.get(index);
        System.out.print("请输入新票价(直接回车保持原值): ");
        String priceInput = scanner.nextLine();

        if (!priceInput.isEmpty()) {
            try {
                double newPrice = Double.parseDouble(priceInput);
                screening.setPrice(newPrice);

                if (cinemaService.updateScreening(screening.getScreeningId(), screening)) {
                    System.out.println("场次票价更新成功！");
                    Logger.info("更新场次票价: " + screening.getMovie().getTitle(),
                            currentUser.getUsername());
                } else {
                    System.out.println("场次票价更新失败！");
                }
            } catch (NumberFormatException e) {
                System.out.println("价格格式错误");
            }
        }
    }

    private static void deleteScreening() {
        listAllScreenings();
        System.out.print("\n请输入要删除的场次编号: ");
        int index = getIntInput("") - 1;
        List<Screening> screenings = cinemaService.getAllScreenings();

        if (index < 0 || index >= screenings.size()) {
            System.out.println("无效的场次编号");
            return;
        }

        Screening screening = screenings.get(index);
        System.out.print("确定要删除场次《" + screening.getMovie().getTitle() +
                "》吗？(y/N): ");
        String confirm = scanner.nextLine();

        if ("y".equalsIgnoreCase(confirm)) {
            if (cinemaService.deleteScreening(screening.getScreeningId())) {
                System.out.println("场次删除成功！");
                Logger.info("删除场次: " + screening.getMovie().getTitle(),
                        currentUser.getUsername());
            } else {
                System.out.println("场次删除失败！");
            }
        } else {
            System.out.println("取消删除操作");
        }
    }

    private static void showStatistics() {
        System.out.println("\n=== 销售统计 ===");
        double todayRevenue = ticketService.getDailyRevenue(LocalDateTime.now());
        System.out.printf("今日总收入: ¥%.2f%n", todayRevenue);

        // 这里可以添加更多统计信息
        System.out.println("更多统计功能开发中...");
    }

    // ==================== 经理菜单 ====================
    private static void showManagerMenu() {
        while (true) {
            System.out.println("\n=== 经理菜单 ===");
            System.out.println("1. 电影管理");
            System.out.println("2. 场次管理");
            System.out.println("3. 售票功能");
            System.out.println("4. 退票功能");
            System.out.println("5. 销售统计");
            System.out.println("6. 退出登录");
            System.out.println("===============");

            int choice = getIntInput("请选择操作: ");
            switch (choice) {
                case 1: manageMovies(); break;
                case 2: manageScreenings(); break;
                case 3: sellTickets(); break;
                case 4: refundTickets(); break;
                case 5: showStatistics(); break;
                case 6:
                    Logger.info("经理退出登录", currentUser.getUsername());
                    return;
                default: System.out.println("无效选择！");
            }
        }
    }

    // ==================== 前台菜单 ====================
    private static void showFrontDeskMenu() {
        while (true) {
            System.out.println("\n=== 前台菜单 ===");
            System.out.println("1. 查看电影");
            System.out.println("2. 查看场次");
            System.out.println("3. 售票功能");
            System.out.println("4. 退票功能");
            System.out.println("5. 退出登录");
            System.out.println("===============");

            int choice = getIntInput("请选择操作: ");
            switch (choice) {
                case 1: listShowingMovies(); break;
                case 2: listTodayScreenings(); break;
                case 3: sellTickets(); break;
                case 4: refundTickets(); break;
                case 5:
                    Logger.info("前台退出登录", currentUser.getUsername());
                    return;
                default: System.out.println("无效选择！");
            }
        }
    }

    // ==================== 售票功能 ====================
    private static void sellTickets() {
        System.out.println("\n=== 售票功能 ===");

        // 选择场次
        List<Screening> screenings = cinemaService.getScreeningsThisWeek();
        if (screenings.isEmpty()) {
            System.out.println("暂无可用场次");
            return;
        }

        System.out.println("=== 可选场次 ===");
        for (int i = 0; i < screenings.size(); i++) {
            Screening screening = screenings.get(i);
            System.out.printf("%d. %s - %s - ¥%.2f - 余票: %d%n",
                    i + 1, screening.getMovie().getTitle(),
                    screening.getStartTime().format(DateTimeFormatter.ofPattern("MM-dd HH:mm")),
                    screening.getPrice(), screening.getAvailableSeats());
        }

        int screeningIndex = getIntInput("请选择场次编号: ") - 1;
        if (screeningIndex < 0 || screeningIndex >= screenings.size()) {
            System.out.println("无效的场次编号");
            return;
        }

        Screening selectedScreening = screenings.get(screeningIndex);

        // 显示座位图
        selectedScreening.getHall().displaySeatMap();

        // 选择座位
        System.out.print("请输入座位号(格式: 排-座，多个用逗号分隔): ");
        String[] seatNumbers = scanner.nextLine().split(",");

        // 输入购票人信息
        System.out.print("请输入购票人姓名: ");
        String purchaser = scanner.nextLine();

        // 售票
        for (String seatNumber : seatNumbers) {
            seatNumber = seatNumber.trim();
            Ticket ticket = ticketService.purchaseTicket(selectedScreening, seatNumber, purchaser);
            if (ticket != null) {
                System.out.println("售票成功！");
                System.out.println(ticket);
                Logger.info("售出票: " + selectedScreening.getMovie().getTitle() +
                        " - " + seatNumber, currentUser.getUsername());
            } else {
                System.out.println("座位 " + seatNumber + " 售票失败");
            }
        }
    }

    // ==================== 退票功能 ====================
    private static void refundTickets() {
        System.out.println("\n=== 退票功能 ===");
        System.out.print("请输入票号: ");
        String ticketId = scanner.nextLine();

        Ticket ticket = ticketService.getTicketById(ticketId);
        if (ticket == null) {
            System.out.println("票号不存在");
            return;
        }

        System.out.println("找到票务信息:");
        System.out.println(ticket);

        if (!ticket.canRefund()) {
            System.out.println("已超过退票时间，无法退票");
            return;
        }

        double refundAmount = ticket.getRefundAmount();
        System.out.printf("可退款金额: ¥%.2f%n", refundAmount);

        System.out.print("确认退票吗？(y/N): ");
        String confirm = scanner.nextLine();

        if ("y".equalsIgnoreCase(confirm)) {
            if (ticketService.refundTicket(ticketId)) {
                System.out.println("退票成功！");
                Logger.info("退票: " + ticketId, currentUser.getUsername());
            } else {
                System.out.println("退票失败");
            }
        } else {
            System.out.println("取消退票操作");
        }
    }

    // ==================== 工具方法 ====================
    private static void showSystemInfo() {
        System.out.println("\n--- 系统信息 ---");
        System.out.println("版本: 0.3.0 - 完整功能");
        System.out.println("用户数: " + authService.getUserCount());
        System.out.println("电影数: " + movieService.getAllMovies().size());
        System.out.println("场次数: " + cinemaService.getAllScreenings().size());
        System.out.println("默认管理员: admin / yuuinfo#777");
        System.out.println("----------------");
    }

    private static int getIntInput(String prompt) {
        while (true) {
            try {
                System.out.print(prompt);
                return Integer.parseInt(scanner.nextLine());
            } catch (NumberFormatException e) {
                System.out.println("请输入有效的数字！");
            }
        }
    }

    private static double getDoubleInput(String prompt) {
        while (true) {
            try {
                if (!prompt.isEmpty()) System.out.print(prompt);
                return Double.parseDouble(scanner.nextLine());
            } catch (NumberFormatException e) {
                System.out.println("请输入有效的数字！");
            }
        }
    }

    private static void cleanup() {
        System.out.println("\n正在关闭系统...");
        scanner.close();
        Logger.close();
        System.out.println("感谢使用万东电影院管理系统！");
        System.out.println("==========================================");
    }
}